package com.cyberypower.sjs.jabber;

import com.cyberypower.sjs.common.Config;
import com.cyberypower.sjs.common.Log;
import org.apache.log4j.Logger;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.packet.Message;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;

public class JabberClientSocket {

    private Logger log = Logger.getLogger(this.getClass());

    private JabberAddress jabberAddress;

    private Chat chat;

    private OutputStream out;

    private String threadID;

    public String getThreadID() {
        return threadID;
    }


    public Object getFlag() {
        return flag;
    }

    private final Object flag = new Object();
    private boolean pleaseWait = false;

    public boolean isPleaseWait() {
        return pleaseWait;
    }

    public void setPleaseWait(boolean pleaseWait) {
        this.pleaseWait = pleaseWait;
    }

    public JabberClientSocket(JabberAddress jabberAddress, Chat chat) {
        threadID = chat.getThreadID();
        this.jabberAddress = jabberAddress;
        this.chat = chat;


        MessageListener messageListener = new MessageListener() {
            private Logger log = Logger.getLogger(this.getClass());

            public void processMessage(Chat chat, Message msg) {
                String body = msg.getBody();
                receivedmessages++;

                if (body.trim().equals(Config.INIT_CHAT)) {
                    log.debug("received JABBER INIT_CHAT (" + chat.getThreadID() + ")");
                    return;
                }
                if (body.trim().equals(Config.CLOSE_CONNECTION)) {
                    try {
                        out.close();
                        has_to_close = true;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    log.debug("received JABBER CLOSE_CONNECTION (" + chat.getThreadID() + ")");
                    return;
                }
                if (body.trim().equals(Config.CHAT_INITED_APPROVED)) {
                    synchronized (flag) {
                        pleaseWait = false;
                        flag.notifyAll();
                    }

                    log.debug("received JABBER CHAT_INITED_APPROVED (" + chat.getThreadID() + ")");
                    return;
                }
                try {
                    log.debug("received JABBER message (" + chat.getThreadID() + ")" + Log.cut(body) + "... " + receivedmessages);
                    out.write(JabberEncoder.decode(body));
                    out.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        this.chat.addMessageListener(messageListener);
    }

    private static int receivedmessages = 0;

    private boolean has_to_close = false;

    public boolean isHas_to_close() {
        return has_to_close;
    }

    public void send(ByteBuffer data) throws Exception {
        String mes = JabberEncoder.encode(data);
        chat.sendMessage(mes);
        sendmessages++;
        log.debug("sent to JABBER (" + chat.getThreadID() + "):" + Log.cut(mes) + "...  "
                + chat.getParticipant() + " "
                + sendmessages
        );
    }

    public void sendText(String data) {
        try {
            chat.sendMessage(data);
            sendmessages++;
            log.debug("sent to JABBER (" + chat.getThreadID() + "):" + Log.cut(data) + "...  "
                    + chat.getParticipant() + " "
                    + sendmessages
            );

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static int sendmessages = 0;


    public JabberClientSocket(JabberAddress serverJid) {
        jabberAddress = serverJid;
    }

    public JabberAddress getJabberAddress() {
        return jabberAddress;
    }


    public void setOutput(OutputStream out) {
        this.out = out;
    }


}
